﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Reflection;
using System.Xml;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace Common.Core.Configuration
{
	public static class TypeResolverHelper
	{
		const string typeAttribute = "type";
		public static Type ResolveType( XmlReader reader )
		{
			if (reader.AttributeCount > 0)
			{
				// expect the first attribute to be the name
				for (bool go = reader.MoveToFirstAttribute(); go; go = reader.MoveToNextAttribute())
				{
					if (typeAttribute.Equals(reader.Name))
					{
						Type result = Type.GetType(reader.Value, false);
						if ( result != null )
						{
							reader.MoveToElement();
							return result;
						}
						break;
					}
				}

				// cover the traces ;)
				reader.MoveToElement();
			}
			return null;
		}
	}

	public class NameTypeConfigurationElementCollection<ElementType, CustomElementType> : Microsoft.Practices.EnterpriseLibrary.Common.Configuration.NameTypeConfigurationElementCollection<ElementType, CustomElementType> where ElementType : NameTypeConfigurationElement, new() where CustomElementType : ElementType, new()
	{
		protected override Type RetrieveConfigurationElementType( XmlReader reader )
		{
			try
			{
				return base.RetrieveConfigurationElementType(reader);
			}
			catch ( ConfigurationErrorsException )
			{
				Type target = TypeResolverHelper.ResolveType( reader );
				if ( target != null )
				{
					SettingsView view = new SettingsView();
					Type result = view.ResolveConfigurationType( typeof(ElementType), target );
					if ( result != null )
					{
						return result;
					}
				}
				throw;
			}
		}
	}
}
